<template>
  <div class="maintenancePlanAdd">
    <div class="panel-body">
      <!--工作区-->
      <div class="workplace">
        <div class="list_left">
          <el-table :data="tableData_left" height="550" style="width: 100%" :key="timeStamp">
            <el-table-column prop="id" label="序号" min-width="35%">
            </el-table-column>
            <el-table-column prop="class" label="标注类型" min-width="65%">
            </el-table-column>
          </el-table>
        </div>
        <!--画布-->
        <div class="demo">
          <div class="child-panel-title"
               style="align-item: center; font-size: 200%">
            图形标注
          </div>
          <canvas id="canvas" :width="width" :height="height"></canvas>
          <div class="draw-btn-group">
            <div :class="{active:drawType==''}" title="自由选择" @click="drawTypeChange('')">
              <i class="draw-icon icon-mouse"></i>
            </div>
            <!--          <div :class="{active:drawType=='arrow'}" title="画箭头" @click="drawTypeChange('arrow')">-->
            <!--            <i class="draw-icon icon-1"></i>-->
            <!--          </div>-->
            <div :class="{active:drawType=='text'}" title="文本输入框" @click="drawTypeChange('text')">
              <i class="draw-icon icon-2"></i>
            </div>
            <div :class="{active:drawType=='ellipse'}" title="画圆" @click="drawTypeChange('ellipse')">
              <i class="draw-icon icon-3"></i>
            </div>
            <div :class="{active:drawType=='rectangle'}" title="画矩形" @click="drawTypeChange('rectangle')">
              <i class="draw-icon icon-4"></i>
            </div>
            <div :class="{active:drawType=='polygon'}" title="画多边形" @click="drawPolygon">
              <i class="draw-icon icon-6"></i>
            </div>
            <div :class="{active:drawType=='pen'}" title="笔画" @click="drawTypeChange('pen')">
              <i class="draw-icon icon-7"></i>
            </div>
            <!--          <div :class="{active:drawType=='pentagram'}" title="五角星" @click="drawTypeChange('pentagram')">-->
            <!--            <i class="draw-icon icon-pentagram"></i>-->
            <!--          </div>-->
            <div @click="uploadImg" title="从文件选择图片上传">
              <i class="draw-icon icon-img"></i>
            </div>
            <div @click="loadExpImg" title="加载背景图">
              <i class="draw-icon icon-back"></i>
            </div>
            <div @click="saveDialog" title="保存">
              <i class="draw-icon icon-save"></i>
            </div>
            <div @click="saveDialog" title="标注完成">
              <i class="draw-icon label-save"></i>
            </div>
            <div @click="clear" title="清空标注">
              <i class="draw-icon label-clear"></i>
            </div>
            <div @click="deleteObj" title="删除标注">
              <i class="draw-icon label-delete"></i>
            </div>
            <div @click="zoomIt(1.1)" title="放大">
              <i class="draw-icon zoom-in"></i>
            </div>
            <div @click="zoomIt(0.9)" title="缩小">
              <i class="draw-icon zoom-out"></i>
            </div>
            <div @click="zoomReset" title="重置">
              <i class="draw-icon label-delete"></i>
            </div>
            <!--            <el-button @click="test" class="sBtn sBtnSuc">test</el-button>-->
          </div>
        </div>
        <!--画布结束-->
        <div class="list_right">
          <el-table :data="tableData_right" height="550" style="width: 100%">
            <el-table-column prop="num" label="序号" min-width="25%">
            </el-table-column>
            <el-table-column prop="discussing" label="讨论" min-width="75%">
              <template>
                <el-input
                  type="textarea"
                  :rows="2"
                  placeholder="请输入内容"
                  v-model="textarea"
                >
                </el-input>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </div>
    <input type="file" @change="uploadImgChange" id="imgInput" accept="image/*"/>
    <img id="img" :src="imgSrc"/>
    <!--    <img id="expImg" src="../assets/icons/draw/exp.jpg"/>-->
    <img id="expImg" src="../assets/icons/draw/2014.jpg"/>
    <el-dialog title="标注类别" :visible.sync="dialog" width="250px">
      <el-form>
        <el-form-item>
          <el-input v-model="input" width="20px" @input="onInput()"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialog = false">取 消</el-button>
        <el-button @click="saveLabel()">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  name: "Fabric_test",
  data() {
    return {
      input: '',// 标注完成后输入标签类别
      dialog: false,// 标注完成后显示对话框
      width: 1100,      //画布尺寸
      height: 750,
      rect: [],
      canvas: {},
      showMenu: false,
      x: "",
      y: "",
      relationship: {x: 0, y: 0, zoom: 1},  // 定义变量记录最后一次的偏移量和缩放比例
      panning: false,
      mouseFrom: {},  //画笔起始位置
      mouseTo: {},  //画笔结束位置
      drawType: null,  //当前绘制图像的种类
      canvasObjectIndex: 0,
      textbox: null,
      rectangleLabel: "warning",
      drawWidth: 4, //笔触宽度
      //color: "#e34f51", //画笔颜色
      color: "#008000", //画笔颜色
      drawingObject: null, //当前绘制对象
      moveCount: 1, //绘制移动计数器
      doDrawing: false, // 绘制状态

      //polygon 多边形相关参数
      polygonMode: false,
      pointArray: [],
      lineArray: [],
      activeShape: false,
      activeLine: "",
      line: {},

      delectKlass: {},
      imgFile: {},
      imgSrc: "",

      customs: {  //自定义标签id与标签的类别
        label_id: 0,
        label: ""
      },

      //新增变量
      textarea: "",
      tableData_left: [], //左侧显示已经标注的id与类别
      tableData_right: [],
      table_index: 1,
    };
  },
  watch: {
    // 监控标注的画笔类别
    drawType() {
      this.canvas.selection = !this.drawType;
    },
    width() {
      this.canvas.setWidth(this.width)
    },
    height() {
      this.canvas.setHeight(this.height)
    },
  },
  methods: {
    // dialogue对话框输入更新
    onInput() {
      this.$forceUpdate();
    },
    //  测试按钮
    test() {
      // 获取后端json格式标注
      // this.$ajax.get('http://localhost:8081/get_label').then(response => {
      //   console.log(response);
      //   let data = response.data;
      //   this.clear();
      //   this.canvas.loadFromJSON(data);
      // })

      // this.canvas.forEachObject(function (obj) {
      //   console.log(JSON.stringify(obj))
      // })
      let prefix = "{\"version\":\"3.6.6\",\"objects\":[";
      let res = ""
      this.canvas.getActiveObjects().map(item => {
        item.toObject();
        item.ID = this.customs.label_id + 1;
        item.label = this.customs.label;
        console.log(JSON.stringify(item));
        res = prefix + JSON.stringify(item) + "]}";
        // this.canvas.loadFromJSON(JSON.stringify(item))
        // console.log(JSON.stringify("{\"version\":\"3.6.6\",\"objects\":{\"type\":\"polygon\",\"version\":\"3.6.6\",\"originX\":\"left\",\"originY\":\"top\",\"left\":338.5,\"top\":522.19,\"width\":242,\"height\":204,\"fill\":\"rgba(255, 255, 255, 0)\",\"stroke\":\"#E34F51\",\"strokeWidth\":4,\"strokeDashArray\":null,\"strokeLineCap\":\"butt\",\"strokeDashOffset\":0,\"strokeLineJoin\":\"miter\",\"strokeMiterLimit\":4,\"scaleX\":1,\"scaleY\":1,\"angle\":0,\"flipX\":false,\"flipY\":false,\"opacity\":1,\"shadow\":null,\"visible\":true,\"clipTo\":null,\"backgroundColor\":\"\",\"fillRule\":\"nonzero\",\"paintFirst\":\"fill\",\"globalCompositeOperation\":\"source-over\",\"transformMatrix\":null,\"skewX\":0,\"skewY\":0,\"ID\":\"01\",\"label\":\"阳性\",\"points\":[{\"x\":359.5,\"y\":524.1875},{\"x\":340.5,\"y\":684.1875},{\"x\":512.5,\"y\":728.1875},{\"x\":582.5,\"y\":571.1875}]}}"));
        let label = {
          image_id: "1",
          username: "kaboon",
          label_id: item.ID + '',
          label_detail: res,
          label_class: item.label,
          count: 0
        }

      });
    },
    //  画布清空
    clear() {
      this.canvas.clear();
    },
    // 保存标注后对话框隐藏
    saveDialog() {
      this.dialog = true;
    },
    //  保存标注
    saveLabel() {
      let prefix = "{\"version\":\"3.6.6\",\"objects\":[";
      let res = "";
      let label;
      this.customs.label = this.input;
      this.canvas.getActiveObjects().map(item => {
        item.toObject();
        this.customs.label_id += 1;
        item.ID = this.customs.label_id;
        item.label = this.customs.label;
        console.log(JSON.stringify(item));
        res = prefix + JSON.stringify(item) + "]}";
        // this.canvas.loadFromJSON(JSON.stringify(item))
        // console.log(JSON.stringify("{\"version\":\"3.6.6\",\"objects\":{\"type\":\"polygon\",\"version\":\"3.6.6\",\"originX\":\"left\",\"originY\":\"top\",\"left\":338.5,\"top\":522.19,\"width\":242,\"height\":204,\"fill\":\"rgba(255, 255, 255, 0)\",\"stroke\":\"#E34F51\",\"strokeWidth\":4,\"strokeDashArray\":null,\"strokeLineCap\":\"butt\",\"strokeDashOffset\":0,\"strokeLineJoin\":\"miter\",\"strokeMiterLimit\":4,\"scaleX\":1,\"scaleY\":1,\"angle\":0,\"flipX\":false,\"flipY\":false,\"opacity\":1,\"shadow\":null,\"visible\":true,\"clipTo\":null,\"backgroundColor\":\"\",\"fillRule\":\"nonzero\",\"paintFirst\":\"fill\",\"globalCompositeOperation\":\"source-over\",\"transformMatrix\":null,\"skewX\":0,\"skewY\":0,\"ID\":\"01\",\"label\":\"阳性\",\"points\":[{\"x\":359.5,\"y\":524.1875},{\"x\":340.5,\"y\":684.1875},{\"x\":512.5,\"y\":728.1875},{\"x\":582.5,\"y\":571.1875}]}}"));
        label = {
          image_id: "1",
          username: "kaboon",
          label_id: item.ID + '',
          label_detail: res,
          label_class: item.label,
          count: 0
        }
      });
      this.$ajax.post('http://localhost:8080/label/addLabel', label,
        {
          headers: {'Content-Type': 'application/json;charset=UTF-8'}
        }
      ).then(response => {
        console.log(response);
        if (response.data === 'success') {
          this.openMessage('标注保存成功', 'success', true);
          this.tableData_left.length = 0;
          this.updateTable();
          console.log('准备刷新');
          this.reload();
        } else this.openMessage('标注保存失败，请稍后重试', 'error');
      }).catch((error) => {
        console.log(error);
        this.openMessage('链接服务器失败，请稍后重试', 'error');
      });
      this.dialog = false;
    },
    //  页面刷新
    reload() {
      this.isRouterAlive = false;            //先关闭，
      this.$nextTick(function () {
        this.isRouterAlive = true;         //再打开
      })
    },
    //  更新左侧标签列表
    updateTable() {
      this.$ajax.get('http://localhost:8080/label/selectByImage?image_id=1').then(response => {
        let data = response.data;
        console.log(data);
        for (let i = 0; i < data.length; i++) {
          let tmp = {
            id: data[i]['label_id'],
            class: data[i]['label_class']
          }
          this.tableData_left.push(tmp);
        }
        this.customs.label_id = parseInt(data[data.length - 1]['label_id']);
      })
    },
    //  保存成功或失败后弹出消息框
    openMessage(messageText, messageType, withReload = false) {
      this.$message({
        message: messageText,
        type: messageType
      });
      if (withReload) this.reload();
    },
    // 保存当前画布为png图片
    save() {
      var canvas = document.getElementById('canvas')
      var imgData = canvas.toDataURL('png');
      imgData = imgData.replace('image/png', 'image/octet-stream');

      // 下载后的问题名，可自由指定
      var filename = 'drawingboard_' + (new Date()).getTime() + '.' + 'png';
      this.saveFile(imgData, filename);
    },
    saveFile(data, filename) {
      var save_link = document.createElement('a');
      save_link.href = data;
      save_link.download = filename;

      var event = document.createEvent('MouseEvents');
      event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
      save_link.dispatchEvent(event);
    },
    uploadImg() {
      document.getElementById("imgInput").click();
    },
    // 从已渲染的DOM元素加载图片至canvas
    loadExpImg() {
      var imgElement = document.getElementById("expImg"); //声明我们的图片
      var imgInstance = new fabric.Image(imgElement, {
        selectable: false
        // zIndex:-99,
      });
      //this.canvas.add(imgInstance);
      this.canvas.setBackgroundImage(imgInstance, this.canvas.renderAll.bind(this.canvas));
    },
    // 从文件加载图片至canvas
    uploadImgChange() {
      // 获取文件
      var eleImportInput = document.getElementById("imgInput");
      this.imgFile = eleImportInput.files[0];
      var imgSrc = "",
        imgTitle = "";
      // 从reader中获取选择文件的src
      if (/\.(jpe?g|png|gif)$/i.test(this.imgFile.name)) {
        var reader = new FileReader();
        var _this = this;
        reader.addEventListener(
          "load",
          function () {
            imgTitle = _this.imgFile.name;
            _this.imgSrc = this.result;
          },
          false
        );
        reader.readAsDataURL(this.imgFile);
      }
      var imgElement = document.getElementById("img"); //声明我们的图片

      imgElement.onload = () => {
        this.width = imgElement.width
        this.height = imgElement.height
        var imgInstance = new fabric.Image(imgElement, {
          zIndex: -1,
          selectable: false
        });
        this.canvas.add(imgInstance);
      };
    },
    // 开始绘制时，指定绘画种类
    drawTypeChange(e) {
      this.drawType = e;
      this.canvas.skipTargetFind = !!e
      if (e == "pen") {
        // isDrawingMode为true 才可以自由绘画
        this.canvas.isDrawingMode = true;
      } else {
        this.canvas.isDrawingMode = false;
      }
    },
    // 鼠标按下时触发
    mousedown(e) {
      if (e.e.altKey) {
        this.panning = true;
        this.canvas.selection = false;
        return
      }
      // 记录鼠标按下时的坐标
      var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
      this.mouseFrom.x = xy.x;
      this.mouseFrom.y = xy.y;
      this.doDrawing = true;
      if (this.drawType == "text") {
        this.drawing();
      }

      if (this.textbox) {
        this.textbox.enterEditing();
        this.textbox.hiddenTextarea.focus();
      }
      // 绘制多边形
      if (this.drawType == "polygon") {
        this.canvas.skipTargetFind = false;
        try {
          // 此段为判断是否闭合多边形，点击红点时闭合多边形
          if (this.pointArray.length > 1) {
            // e.target.id == this.pointArray[0].id 表示点击了初始红点
            if (e.target && e.target.id == this.pointArray[0].id) {
              this.generatePolygon();
              this.openMessage("标注完成", "success")
            }
          }
          //未点击红点则继续作画
          if (this.polygonMode) {
            this.addPoint(e);
          }
        } catch (error) {
          console.log(error);
        }
      }
    },
    // 鼠标松开执行
    mouseup(e) {
      this.panning = false;
      this.canvas.selection = true;
      var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
      this.mouseTo.x = xy.x;
      this.mouseTo.y = xy.y;
      this.drawingObject = null;
      this.moveCount = 1;
      if (this.drawType != "polygon") {
        this.doDrawing = false;
      }
    },

    //鼠标移动过程中已经完成了绘制
    mousemove(e) {
      if (this.panning && e && e.e) { // padding 表示是否允许拖动画布
        const delta = new fabric.Point(e.e.movementX, e.e.movementY);
        this.canvas.relativePan(delta);
        //累计每一次移动时候的偏移量
        this.relationship.x += e.e.movementX / this.canvas.getZoom();
        this.relationship.y += e.e.movementY / this.canvas.getZoom();
        return;
      }
      if (this.moveCount % 2 && !this.doDrawing) {
        //减少绘制频率
        return;
      }
      this.moveCount++;
      var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
      this.mouseTo.x = xy.x;
      this.mouseTo.y = xy.y;
      // 多边形与文字框特殊处理
      if (this.drawType != "text" || this.drawType != "polygon") {
        this.drawing(e);
      }
      if (this.drawType == "polygon") {
        if (this.activeLine && this.activeLine.class == "line") {
          var pointer = this.canvas.getPointer(e.e);
          this.activeLine.set({x2: pointer.x, y2: pointer.y});

          var points = this.activeShape.get("points");
          points[this.pointArray.length] = {
            x: pointer.x,
            y: pointer.y,
            zIndex: 1
          };
          this.activeShape.set({
            points: points
          });
          this.canvas.renderAll();
        }
        this.canvas.renderAll();
      }
    },
    deleteObj() {
      this.canvas.getActiveObjects().map(item => {
        this.canvas.remove(item);
      });
    },
    transformMouse(mouseX, mouseY) {
      return {x: mouseX / this.canvas.getZoom(), y: mouseY / this.canvas.getZoom()};
    },
    // 绘制多边形开始，绘制多边形和其他图形不一样，需要单独处理
    drawPolygon() {
      this.drawType = "polygon";
      this.polygonMode = true;
      //这里画的多边形，由顶点与线组成
      this.pointArray = new Array();  // 顶点集合
      this.lineArray = new Array();  //线集合
      this.canvas.isDrawingMode = false;
    },
    addPoint(e) {
      var random = Math.floor(Math.random() * 10000);
      var id = new Date().getTime() + random;
      var circle = new fabric.Circle({
        radius: 5,
        fill: "#ffffff",
        stroke: "#333333",
        strokeWidth: 0.5,
        left: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
        top: (e.pointer.y || e.e.layerY) / this.canvas.getZoom(),
        selectable: false,
        hasBorders: false,
        hasControls: false,
        originX: "center",
        originY: "center",
        id: id,
        objectCaching: false
      });
      if (this.pointArray.length == 0) {
        circle.set({
          fill: "red"
        });
      }
      var points = [
        (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
        (e.pointer.y || e.e.layerY) / this.canvas.getZoom(),
        (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
        (e.pointer.y || e.e.layerY) / this.canvas.getZoom()
      ];

      this.line = new fabric.Line(points, {
        strokeWidth: 4,
        fill: "#999999",
        stroke: "#999999",
        class: "line",
        originX: "center",
        originY: "center",
        selectable: false,
        hasBorders: false,
        hasControls: false,
        evented: false,

        objectCaching: false
      });
      if (this.activeShape) {
        var pos = this.canvas.getPointer(e.e);
        var points = this.activeShape.get("points");
        points.push({
          x: pos.x,
          y: pos.y
        });
        var polygon = new fabric.Polygon(points, {
          stroke: "#333333",
          strokeWidth: 1,
          fill: "#cccccc",
          opacity: 0.3,

          selectable: false,
          hasBorders: false,
          hasControls: false,
          evented: false,
          objectCaching: false
        });
        this.canvas.remove(this.activeShape);
        this.canvas.add(polygon);
        this.activeShape = polygon;
        this.canvas.renderAll();
      } else {
        var polyPoint = [
          {
            x: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
            y: (e.pointer.y || e.e.layerY) / this.canvas.getZoom()
          }
        ];
        var polygon = new fabric.Polygon(polyPoint, {
          stroke: "#333333",
          strokeWidth: 1,
          fill: "#cccccc",
          opacity: 0.3,

          selectable: false,
          hasBorders: false,
          hasControls: false,
          evented: false,
          objectCaching: false
        });
        this.activeShape = polygon;
        this.canvas.add(polygon);
      }
      this.activeLine = this.line;

      this.pointArray.push(circle);
      this.lineArray.push(this.line);
      this.canvas.add(this.line);
      this.canvas.add(circle);
    },
    //  生成多边形
    generatePolygon() {
      var points = new Array();
      this.pointArray.map((point, index) => {
        points.push({
          x: point.left,
          y: point.top
        });
        this.canvas.remove(point);
      });
      this.lineArray.map((line, index) => {
        this.canvas.remove(line);
      });
      this.canvas.remove(this.activeShape).remove(this.activeLine);
      var polygon = new fabric.Polygon(points, {
        stroke: this.color,
        strokeWidth: this.drawWidth,
        fill: "rgba(255, 255, 255, 0)",
        opacity: 1,
        hasBorders: true,
        hasControls: false,
        ID: this.customs.label_id,
        label: this.customs.label
      });
      //polygon.toObject("111","222");
      this.canvas.add(polygon);

      this.activeLine = null;
      this.activeShape = null;
      this.polygonMode = false;
      this.doDrawing = false;
      this.drawType = null;
    },
    drawing(e) {
      if (this.drawingObject) {
        this.canvas.remove(this.drawingObject);
      }
      var canvasObject = null;
      var left = this.mouseFrom.x,
        top = this.mouseFrom.y,
        mouseFrom = this.mouseFrom,
        mouseTo = this.mouseTo;
      switch (this.drawType) {
        case "arrow": //箭头
          var x1 = mouseFrom.x,
            x2 = mouseTo.x,
            y1 = mouseFrom.y,
            y2 = mouseTo.y;
          var w = x2 - x1,
            h = y2 - y1,
            sh = Math.cos(Math.PI / 4) * 16;
          var sin = h / Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2));
          var cos = w / Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2));
          var w1 = (16 * sin) / 4,
            h1 = (16 * cos) / 4,
            centerx = sh * cos,
            centery = sh * sin;
          /**
           * centerx,centery 表示起始点，终点连线与箭头尖端等边三角形交点相对x，y
           * w1 ，h1用于确定四个点
           */

          var path = " M " + x1 + " " + y1;
          path += " L " + (x2 - centerx + w1) + " " + (y2 - centery - h1);
          path +=
            " L " + (x2 - centerx + w1 * 2) + " " + (y2 - centery - h1 * 2);
          path += " L " + x2 + " " + y2;
          path +=
            " L " + (x2 - centerx - w1 * 2) + " " + (y2 - centery + h1 * 2);
          path += " L " + (x2 - centerx - w1) + " " + (y2 - centery + h1);
          path += " Z";
          canvasObject = new fabric.Path(path, {
            stroke: this.color,
            fill: this.color,
            strokeWidth: this.drawWidth
          });
          break;
        case "pentagram": //五角星
          var x1 = mouseFrom.x,
            x2 = mouseTo.x,
            y1 = mouseFrom.y,
            y2 = mouseTo.y;
          /**
           * 实现思路  (x1,y1)表示鼠标起始的位置 (x2,y2)表示鼠标抬起的位置
           * r 表示五边形外圈圆的半径，这里建议自己画个图理解
           * 正五边形夹角为36度。计算出cos18°，sin18°备用
           */
          var w = Math.abs(x2 - x1),
            h = Math.abs(y2 - y1),
            r = Math.sqrt(w * w + h * h)
          var cos18 = Math.cos(18 * Math.PI / 180)
          var sin18 = Math.sin(18 * Math.PI / 180)

          /**
           * 算出对应五个点的坐标转化为路径
           */
          var point1 = [x1, y1 + r]
          var point2 = [x1 + 2 * r * (sin18), y1 + r - 2 * r * (cos18)]
          var point3 = [x1 - r * (cos18), y1 + r * (sin18)]
          var point4 = [x1 + r * (cos18), y1 + r * (sin18)]
          var point5 = [x1 - 2 * r * (sin18), y1 + r - 2 * r * (cos18)]

          var path = " M " + point1[0] + " " + point1[1]
          path += " L " + point2[0] + " " + point2[1]
          path += " L " + point3[0] + " " + point3[1]
          path += " L " + point4[0] + " " + point4[1]
          path += " L " + point5[0] + " " + point5[1]
          path += " Z";
          canvasObject = new fabric.Path(path, {
            stroke: this.color,
            fill: this.color,
            strokeWidth: this.drawWidth,
            // angle:180,  //设置旋转角度
          });
          break;
        case "ellipse": //椭圆
          // 按shift时画正圆，只有在鼠标移动时才执行这个，所以按了shift但是没有拖动鼠标将不会画圆
          if (e.e.shiftKey) {
            mouseTo.x - left > mouseTo.y - top ? mouseTo.y = top + mouseTo.x - left : mouseTo.x = left + mouseTo.y - top
          }
          var radius =
            Math.sqrt(
              (mouseTo.x - left) * (mouseTo.x - left) +
              (mouseTo.y - top) * (mouseTo.y - top)
            ) / 2;
          canvasObject = new fabric.Ellipse({
            left: (mouseTo.x - left) / 2 + left,
            top: (mouseTo.y - top) / 2 + top,
            stroke: this.color,
            fill: "rgba(255, 255, 255, 0)",
            originX: "center",
            originY: "center",
            rx: Math.abs(left - mouseTo.x) / 2,
            ry: Math.abs(top - mouseTo.y) / 2,
            strokeWidth: this.drawWidth
          });
          break;
        case "rectangle": //长方形
          // 按shift时画正方型
          if (e.e.shiftKey) {
            mouseTo.x - left > mouseTo.y - top ? mouseTo.y = top + mouseTo.x - left : mouseTo.x = left + mouseTo.y - top
          }
          var path =
            "M " +
            mouseFrom.x +
            " " +
            mouseFrom.y +
            " L " +
            mouseTo.x +
            " " +
            mouseFrom.y +
            " L " +
            mouseTo.x +
            " " +
            mouseTo.y +
            " L " +
            mouseFrom.x +
            " " +
            mouseTo.y +
            " L " +
            mouseFrom.x +
            " " +
            mouseFrom.y +
            " z";
          canvasObject = new fabric.Path(path, {
            left: left,
            top: top,
            stroke: this.color,
            strokeWidth: this.drawWidth,
            fill: "rgba(255, 255, 255, 0)",
            hasControls: false
          });
          //也可以使用fabric.Rect
          break;
        case "text": //文本框
          this.textbox = new fabric.Textbox("", {
            left: mouseFrom.x,
            top: mouseFrom.y - 10,
            // width: 150,
            fontSize: 16,
            borderColor: this.color,
            fill: this.color,
            hasControls: false
          });
          this.canvas.add(this.textbox);
          this.textbox.enterEditing();
          this.textbox.hiddenTextarea.focus();
          break;

        default:
          break;
      }

      if (canvasObject) {
        // canvasObject.index = getCanvasObjectIndex();\
        this.canvas.add(canvasObject); //.setActiveObject(canvasObject)
        this.drawingObject = canvasObject;
      }
    },
    zoomIt(factor) {
      this.canvas.setZoom(this.canvas.getZoom() * factor);
    },
    zoomReset() {
      this.canvas.setViewportTransform([1, 0, 0, 1, 0, 0]);
    }
  },
  mounted() {
    // Object可以自定义添加属性
    fabric.Object.prototype.toObject = (function (toObject) {
      return function (properties) {
        return fabric.util.object.extend(toObject.call(this, properties), {
          ID: this.ID,
          label: this.label
        });
      };
    })(fabric.Object.prototype.toObject);
    //  新建画布
    this.canvas = new fabric.Canvas("canvas", {
      // skipTargetFind: false, //当为真时，跳过目标检测。目标检测将返回始终未定义。点击选择将无效
      // selectable: false,  //为false时，不能选择对象进行修改
      // selection: false   // 是否可以多个对象为一组
    });
    // var rect = new fabric.Rect({
    //   left:100,//距离画布左侧的距离，单位是像素
    //   top:100,//距离画布上边的距离
    //   fill:'red',//填充的颜色
    //   width:30,//方形的宽度
    //   height:30//方形的高度
    // });
    // this.canvas.add(rect)
    this.canvas.selectionColor = "rgba(0,0,0,0.05)";
    this.canvas.on("mouse:down", this.mousedown);
    this.canvas.on("mouse:move", this.mousemove);
    this.canvas.on("mouse:up", this.mouseup);
    document.onwheel = e => {
      // 按住ctrl + 滚轮实现放大缩小
      if (e.altKey) {
        e.preventDefault();
        let zoom = (e.deltaY > 0 ? 0.1 : -0.1) + this.canvas.getZoom();
        zoom = Math.max(0.1, zoom);
        zoom = Math.min(5, zoom);
        if (zoom === this.relationship.zoom) return;
        const [x, y] = [e.offsetX, e.offsetY];
        // 计算缩放时产生的偏移量 这是重点代码
        this.relationship.x += x / zoom - x / this.relationship.zoom;
        this.relationship.y += y / zoom - y / this.relationship.zoom;
        const zoomPoint = new fabric.Point(x, y);
        this.canvas.zoomToPoint(zoomPoint, zoom);
        this.relationship.zoom = zoom;
      }
    };
    document.onkeydown = e => {
      // 键盘 delect删除所选元素
      if (e.keyCode == 46) {
        this.deleteObj();
      }
      // ctrl+z 删除最近添加的元素
      if (e.keyCode == 90 && e.ctrlKey) {
        this.canvas.remove(
          this.canvas.getObjects()[this.canvas.getObjects().length - 1]
        );
      }
    };
    this.loadExpImg();
    //  页面加载时获取本图片所有标注
    this.$ajax.get('http://localhost:8080/label/selectByImage?image_id=1').then(response => {
      let data = response.data;
      console.log(data);
      for (let i = 0; i < data.length; i++) {
        let tmpcanvas = new fabric.Canvas();
        tmpcanvas.loadFromJSON(data[i]['label_detail']);
        console.log(data[i]['label_detail']);
        for (let k in tmpcanvas.getObjects()) {
          this.canvas.add(tmpcanvas._objects[k]);
        }
        this.canvas.renderAll();
      }
    });
    this.updateTable();
    this.loadExpImg();
    this.canvas.renderAll();
  }
}
;
</script>

<style lang="scss" scoped>
.el-container {
  flex-direction: column;
}

img,
input {
  display: none;
}

.workplace {
  width: 100%;
}

.list_left {
  width: 250px;
  float: left;
  margin-left: 10px;
}

.demo {
  float: left;
  margin: 5px 50px 0 50px;
}

.list_right {
  width: 350px;
  float: left;
}

canvas {
  border: 1px dashed black;
}

.draw-btn-group {
  // width: 1270px;
  margin-top: 10px;
  display: flex;
  align-items: center;
  justify-content: flex-start;

  & > div {
    background: #fafafa;
    cursor: pointer;

    &:hover {
      background: #eee;
    }

    i {
      display: flex;
      background-repeat: no-repeat;
      background-size: 80%;
      background-position: 50% 50%;
      height: 30px;
      width: 30px;
    }

    .icon-1 {
      background-image: url("../assets/icons/draw/1.png");
    }

    .icon-pentagram {
      background-image: url("../assets/icons/draw/pentagram.png");
    }

    .icon-2 {
      background-image: url("../assets/icons/draw/2.png");
    }

    .icon-3 {
      background-image: url("../assets/icons/draw/3.png");
    }

    .icon-4 {
      background-image: url("../assets/icons/draw/4.png");
      background-size: 75%;
    }

    .icon-5 {
      background-image: url("../assets/icons/draw/5.png");
      background-size: 70%;
    }

    .icon-6 {
      background-image: url("../assets/icons/draw/6.png");
    }

    .icon-7 {
      background-image: url("../assets/icons/draw/7.png");
      background-size: 80%;
    }

    .icon-del {
      background-image: url("../assets/icons/draw/del.png");
      background-size: 90%;
    }

    .icon-img {
      background-image: url("../assets/icons/draw/img.png");
      background-size: 80%;
    }

    .icon-back {
      background-image: url("../assets/icons/draw/back.png");
      background-size: 75%;
    }

    .icon-save {
      background-image: url("../assets/icons/draw/save.png");
      background-size: 80%;
    }

    .label-save {
      background-image: url("../assets/icons/draw/labelsave.jpg");
      background-size: 80%;
    }

    .label-clear {
      background-image: url("../assets/icons/draw/clearall.jpg");
      background-size: 60%;
    }

    .label-delete {
      background-image: url("../assets/icons/draw/delete.jpg");
      background-size: 60%;
    }

    .icon-mouse {
      background-image: url("../assets/icons/draw/mouse.png");
      background-size: 60%;
    }

    .zoom-in {
      background-image: url("../assets/icons/draw/zoom-in.png");
      background-size: 100%;
    }

    .zoom-out {
      background-image: url("../assets/icons/draw/zoom-out.png");
      background-size: 100%;
    }
  }

  .active {
    background: #eee;
  }
}
</style>
